#ifndef __WPSMVC_H__
#define __WPSMVC_H__

#include <vector>
#include <map>

enum MVCLayerType
{
	LAYER_DOCUMENT,
	LAYER_DRAWING,
	LAYER_CHART,
	LAYER_SMARTART,
	LAYER_MAX,
};

enum MVCLayoutType
{
	LAYOUT_NORMAL,
	LAYOUT_OUTLINE,
	LAYOUT_WEB,
	LAYOUT_READING,
	LAYOUT_MAX,
};

enum ModelType
{
	modelLayer,
	modelShape,
	modelMax,
};

class AbstractContext
{
public:
	virtual ~AbstractContext();
	virtual int getViewId() = 0;
	virtual int getLayoutId() = 0;
	virtual int getLayoutType() = 0;
};

class AbstractObject
{
	typedef std::vector<AbstractObject*> Children;

public:
	AbstractObject();
	virtual ~AbstractObject();
	virtual void destory();	
	virtual AbstractObject* getChildObject(int index);
	virtual int getChildCount();

protected:
	virtual void addChild(AbstractObject*);
	virtual void removeChild(AbstractObject*);
	virtual void insertChild(int index, AbstractObject*);

protected:
	AbstractObject* m_parent;
	Children m_children;
};

class AbstractLayer;
class AbstractVisual;
class AbstractModel
	: public AbstractObject
{
	friend AbstractLayer;
	friend AbstractVisual;
	typedef std::map<int, AbstractVisual*> Visuals;
	typedef AbstractObject ClassBase;

public:
	AbstractModel();
	virtual ~AbstractModel();
	virtual void destory();	
	virtual AbstractModel* getChild(int index);
	virtual AbstractVisual* getVisual(AbstractContext*);
	virtual int getVisualCount();
	virtual int getModelType() = 0;

protected:
	virtual AbstractVisual* createVisual(AbstractContext*);
	virtual void addChild(AbstractObject*);
	virtual void addVisual(AbstractContext*, AbstractVisual*);
	virtual void removeVisual(AbstractContext*, AbstractVisual*);

private:
	AbstractModel* getParent();

protected:
	AbstractLayer* m_layer;
	Visuals m_visuals;
};

class AbstractVisual
	: public AbstractObject
{
	friend AbstractModel;
	typedef AbstractObject ClassBase;
	typedef std::vector<AbstractVisual*> SubVisuals;

public:
	AbstractVisual();
	virtual ~AbstractVisual();
	virtual void destory() override;
	virtual AbstractModel* getModel();
	virtual AbstractVisual* getChild(int index);
	virtual AbstractVisual* getSupVisual();
	virtual AbstractVisual* getSubVisual(int index);
	virtual int getSubVisualCount();

public:
	virtual void addChild(AbstractObject*);
	virtual void addSubVisual(AbstractVisual*);
	virtual void removeSubVisual(AbstractVisual*);

private:
	virtual void insertSubVisual(int index, AbstractVisual*);

private:
	AbstractModel* m_model;
	AbstractVisual* m_layer;
	SubVisuals m_subVisuals;
	AbstractVisual* m_supVisual;
	AbstractContext* m_context;
};

class Cellection
{
	typedef std::vector<AbstractModel*> Models;
	typedef std::vector<AbstractLayer*> Layers;

private:
	Models m_models;
	Layers m_layers;
};

class AbstractLayer
	: public AbstractModel
{
	typedef AbstractModel ClassBase;
	typedef std::map<int, Cellection*> Cellections;

public:
	virtual int getLayerType() = 0;
	virtual Cellection* getCellection(AbstractContext*);

protected:
	virtual AbstractVisual* createVisual(AbstractContext*) override;
	virtual void addChild(AbstractObject*) override;
	
private:
	Cellections m_cellections;
};

class AbstractVisualFactory;
class AbstractLayerVisual
	: public AbstractVisual
{
public:
	virtual AbstractVisualFactory* getVisualFactory() = 0;
};

class AbstractVisualFactory
{
public:
	virtual ~AbstractVisualFactory();
	virtual AbstractVisual* createNormalVisual(AbstractModel*, AbstractContext*) = 0;
	virtual AbstractLayerVisual* createLayerVisual(AbstractLayer*, AbstractContext*) = 0;
};

#endif /* __WPSMVC_H__ */
